// MIT License
// 开源地址：https://gitee.com/co1024/AbcMvc
// Copyright (c) 2021-2023 1024
// Abc.Mvc=Furion+EF+SqlSugar+Pear layui admin.

using Furion.DynamicApiController;

namespace Abc.Application.HtAdminServices;

/// <summary>
///     角色
/// </summary>
[ApiDescriptionSettings("HtAdmin", Name = "HtRole")]
[MaApi("API", "HtRole", "角色", PCode = "API")]
[IgnoreAntiforgeryToken]
public class HtRoleService : IHtRoleService, ITransient, IDynamicApiController
{
    private readonly ILogger<HtRoleService> _logger;
    private readonly IRepository<SysRole> _repository;

    public HtRoleService(ILogger<HtRoleService> logger, IRepository<SysRole> repository)
    {
        _logger = logger;
        _repository = repository;
    }

    ///// <summary>
    ///// 刷新缓存
    ///// </summary>
    ///// <returns></returns>
    //public override async Task<List<SysRole>> RefreshCacheAsync()
    //{
    //    var datas = await base.AsQueryable().Includes(r => r.Menus).WithCache().ToListAsync();
    //    return datas;
    //}

    /// <summary>
    ///     新增或更新一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [MaPermission("新增或更新一条", "InsertOrUpdate")]
    public async Task InsertOrUpdate(HtRoleInput input)
    {
        if (input.Id > 0)
        {
            var dbentity = _repository.FirstOrDefault(r => r.Id == input.Id);
            input.Adapt(dbentity);
        }
        else
        {
            var newEntity = await _repository.InsertAsync(input.Adapt<SysRole>());
        }
    }

    /// <summary>
    ///     删除一条
    /// </summary>
    /// <param name="id"></param>
    [MaPermission("删除一条", "Delete")]
    public async Task Delete(long id)
    {
        await _repository.Where(o => o.Id == id).ExecuteDeleteAsync();
    }

    /// <summary>
    ///     批量删除
    /// </summary>
    /// <param name="ids">需要删除的数据，多条以英文逗号隔开</param>
    [MaPermission("批量删除", "BatchDelete")]
    public async Task BatchDelete(string ids)
    {
        var idtemps = ids.ToIntList();
        await _repository.Where(r => idtemps.Any(a => a == r.Id))
            .ExecuteUpdateAsync(u =>
                u.SetProperty(f => f.IsDeleted, n => true)
            );
    }

    /// <summary>
    ///     查询一条[跟踪实体]
    /// </summary>
    /// <param name="id"></param>
    [MaPermission("查询一条", "Get")]
    public async Task<HtRoleOut> Get(long id)
    {
        var dbentity = await _repository.DetachedEntities.FirstOrDefaultAsync(r => r.Id == id);
        if (dbentity == null) return null;
        return dbentity.Adapt<HtRoleOut>();
    }

    /// <summary>
    ///     分页查询
    /// </summary>
    /// <param name="searchQuery"></param>
    /// <returns></returns>
    [MaPermission("分页查询", "GetAllByPage")]
    public async Task<LayuiPagedList<HtRoleOut>> GetAllByPageToLayui(HtRoleQuery searchQuery)
    {
        //var queryable= _roleRepository.DetachedEntities.AsQueryable();
        //if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        //{
        //    var kw = searchQuery.KeyWords.ToLower();
        //    queryable = queryable.Where(o => o.No.Contains(kw));
        //}

        var pageResult = _repository.DetachedEntities.OrderByDescending(o => o.Id)
                .ProjectToType<HtRoleOut>()
            ;
        return await pageResult.ToLayuiPagedListAsync(searchQuery.Page, searchQuery.Limit);
    }

    /// <summary>
    ///     设置角色权限
    /// </summary>
    /// <param name="input">输入role对象</param>
    /// <returns></returns>
    [MaPermission("设置角色权限", "SetRolePermission")]
    public async Task SetRolePermission(HtRoleInput input)
    {
        //判断角色名称是否存在
        if (input.Id > 0)
        {
            if (_repository.Any(o => o.Id != input.Id && input.Name == o.Name))
                throw Oops.Bah($"角色名称：【{input.Name}】 以存在");
        }
        else
        {
            if (_repository.Any(o => input.Name == o.Name)) throw Oops.Bah($"角色名称：【{input.Name}】 以存在");
        }

        var dbrole = await _repository.Include(o => o.Menus).FirstOrDefaultAsync(o => o.Id == input.Id);
        if (dbrole == null)
        {
            dbrole = input.Adapt<SysRole>();
            //dbrole.Menus = new List<SysMenu>();
            dbrole.Menus = new List<SysMenu>();

            var role = await _repository.InsertNowAsync(dbrole);
            input.Id = role.Entity.Id;
        }
        else
            input.Adapt(dbrole);

        //await _db.UpdateAsync(dbrole);
        //获取全部菜单数据
        var dbmenus = await _repository.Change<SysMenu>().DetachedEntities.ToListAsync();
        var permissions = input.Permissionstrs.ToList(new[] { ',' });
        foreach (var permissionid in dbrole.Menus.Select(o => o.Code).ToList())
        {
            var permission = dbrole.Menus.First(o => o.Code.Trim().ToLower() == permissionid.Trim().ToLower());
            if (permissions.All(o => o != permissionid)) dbrole.Menus.Remove(permission);
        }

        var roleMenus = new List<SysRoleMenu>();
        foreach (var permissionid in permissions)
        {
            var dbmenu = dbmenus.FirstOrDefault(o => o.Code.Trim().ToLower() == permissionid.Trim().ToLower());
            if (dbmenu == null) continue;
            //如果还有上级，则跳过，只关联末尾节点
            if (dbmenus.Any(o =>
                    !string.IsNullOrWhiteSpace(o.PCode) &&
                    o.PCode.Trim().ToLower() == dbmenu.Code.Trim().ToLower())) continue;
            if (dbrole.Menus.Any(o => o.Id == dbmenu.Id)) continue; //以存在跳过
            roleMenus.Add(new SysRoleMenu { MenuId = dbmenu.Id.ToInt32(), RoleId = input.Id.Value });
        }

        await _repository.Change<SysRoleMenu>().InsertAsync(roleMenus);
    }

    /// <summary>
    ///     获取角色 权限 Dtree 树
    /// </summary>
    /// <param name="roleid"></param>
    /// <param name="area">区域</param>
    /// <returns></returns>
    [MaPermission("获取角色 权限 Dtree 树", "GetRoleDtreeCheck")]
    public async Task<Dtree> GetRoleDtreeCheck(long roleid = 0, string area = "HtAdmin")
    {
        SysRole role = null;
        if (roleid > 0)
            //var roleentities = await _db.GetCacheListAsync();
            role = await _repository.DetachedEntities.Include(o => o.Menus).FirstAsync(o => o.Id == roleid);
        //获取区域菜单
        var menus = await _repository.Change<SysMenu>().DetachedEntities.ToListAsync();
        //只查询显示可用且可显示的菜单
        menus = menus.Where(o => o.IsEnable).ToList();

        var rolemenus = role?.Menus?.ToList() ?? new List<SysMenu>();
        //var dtreeitems = GetDtreeCheckItems(menus, rolePermissions);

        var alldatas = menus
            .Where(o => o.Area == "HtAdmin")
            .Select(o => new DtreeEntity { id = o.Code, pid = o.PCode, name = o.Name, sort = o.Sort });
        var selectdatas =
            rolemenus.Select(o => new DtreeEntity { id = o.Code, pid = o.PCode, name = o.Name, sort = o.Sort });

        var dtree = alldatas.GetDtreeCheck("HtAdmin", selectdatas);
        ;
        return dtree;
    }

    /// <summary>
    ///     设置状态
    /// </summary>
    /// <param name="id"></param>
    /// <param name="state"></param>
    /// <param name="field">字段名</param>
    /// <returns></returns>
    [MaPermission("设置状态", "SetState")]
    public async Task SetState(long id, bool state, string field)
    {
        var entity = await _repository.FindAsync(id);

        switch (field.ToLower())
        {
            case "isenable":
            {
                entity.IsEnable = state;
            }
                break;
            //case "isdeleted":
            //    {
            //        entity.IsDeleted = state;
            //    }
            //    break;
        }
    }

    /// <summary>
    ///     查询所有
    /// </summary>
    /// <returns></returns>
    [MaPermission("查询所有", "GetAll")]
    public async Task<List<HtRoleOut>> GetAll()
    {
        var entities = await _repository.DetachedEntities.ProjectToType<HtRoleOut>().ToListAsync();

        return entities;
    }
}